
# ~ ho = "━"
# ~ ve = "┃"
# ~ br1 = "┣"
# ~ br2 = "┗"
ho = "━ "
ve = "┃ "
br1 = "┣ "
br2 = "┗ "



def write(writer, si, o):
    writer[-1][-2:] = [si, ho, o]

def newline(writer):
    nl = []
    for x in writer[-1]:
        if x in ["  ", ho, br2]:
            nl.append("  ")
        elif x in [ve, br1]:
            nl.append(ve)
    writer.append(nl)

def deep(writer):
    writer[-1].append(None)
    writer[-1].append(None)

def back(writer):
    writer[-1].pop()
    writer[-1].pop()

def show(writer):
    for x in writer:
        print("".join(x))

def tree_part(writer, l, name, member):
    assert len(l) >= 1
    it = zip(l, l[1:] + ["end"])
    for i, (o, ne) in enumerate(it):
        na = name(o)
        me = member(o)
        if ne != "end":
            write(writer, br1, na)
            newline(writer)
        else:
            write(writer, br2, na)
            newline(writer)
        if len(me) > 0:
            deep(writer)
            tree_part(writer, me, name, member)
            back(writer)

def tree(x, name, member):
    na = name(x)
    me = member(x)
    print(na)
    writer = [[]]
    if len(me) > 0:
        tree_part(writer, me, name, member)
        show(writer)

__all__ = ["tree"]

if __name__ == "__main__":
    l = [[1, [2, [7, 8, 9], 3]], [4, 5], 6]

    def name(o):
        if isinstance(o, (list, tuple)):
            return f"{type(o).__name__}[{len(o)}]"
        else:
            return str(o)

    def member(o):
        if isinstance(o, (list, tuple)):
            return o
        else:
            return []


    tree(l, name, member)
    tree(l[0], name, member)
